package customer

import (
	"goskeleton/app/global/variable"
	"goskeleton/app/model"
	"goskeleton/app/utils/data_bind"
	
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

func CreateCustomerFactory(sqlType string) *CustomerModel {
	return &CustomerModel{BaseModel: model.BaseModel{DB: model.UseDbConn(sqlType)}}
}

type CustomerModel struct {
	model.BaseModel
	Name           string `gorm:"column:name" json:"name"`           // 客户姓名
	Gender         int    `gorm:"column:gender" json:"gender"`       // 性别 (0:未知,1:男,2:女)
	Phone          string `gorm:"column:phone" json:"phone"`         // 电话
	Email          string `gorm:"column:email" json:"email"`         // 邮箱
	Company        string `gorm:"column:company" json:"company"`    // 公司
	Position       string `gorm:"column:position" json:"position"`   // 职位
	CustomerStatus int    `gorm:"column:customer_status" json:"customer_status"` // 客户状态 (0:禁用,1:启用)
	CreatedAt      string `gorm:"column:created_at" json:"created_at"` // 创建时间
	UpdatedAt      string `gorm:"column:updated_at" json:"updated_at"` // 更新时间
	DeleteStatus   int    `gorm:"column:delete_status" json:"delete_status"` // 是否删除 1否 2是
}

// CustomerModel sets the name of the table in the database
func (cust *CustomerModel) TableName() string {

	return "tb_customer"
}

func (cust *CustomerModel) InsertData(c *gin.Context) bool {
	var tmp CustomerModel
	if err := data_bind.ShouldBindFormDataToModel(c, &tmp); err == nil {
		variable.ZapLog.Warn("createData_1:",zap.Any("c",c))
		variable.ZapLog.Warn("createData_2:",zap.Any("tmp",tmp))
		if res := cust.Create(&tmp); res.Error == nil {
			return true
		} else {
			variable.ZapLog.Error("CustomerModel 数据新增出错", zap.Error(res.Error))
		}
	} else {
		variable.ZapLog.Error("CustomerModel 数据绑定出错", zap.Error(err))
	}
	return false
}

// 根据关键词查询用户表的条数
func (cust *CustomerModel) getCounts() (counts int64) {
	sql := "select  count(*) as counts from tb_customer where delete_status = ?"
	if _ = cust.Raw(sql,1).First(&counts); counts > 0 {
		return counts
	} else {
		return 0
	}
}

func (cust *CustomerModel) getCountsByWhere(name string, company string, customerStatus int) (totalCount int64) {
	query := cust.Model(cust)
	if name != "" {
		query = query.Where("name like ?", "%"+name+"%")
	}
	if company != "" {
		query = query.Where("company like ?", "%"+company+"%")
	}
	if customerStatus >0 {
		query = query.Where("customer_status = ?", customerStatus)
	}
	query.Where("delete_status = ?", 1)
	if res := query.Count(&totalCount); res.Error == nil {
		return totalCount
	}
	return 0
}

func (cust *CustomerModel) UpdateData(c *gin.Context) bool {
	var tmp CustomerModel
	if err := data_bind.ShouldBindFormDataToModel(c, &tmp); err == nil {
		if res := cust.Updates(&tmp); res.Error == nil {
			return true
		} else {
			variable.ZapLog.Error("CustomerModel 数据更新出错", zap.Error(res.Error))
			return false

		}
	} else {
		variable.ZapLog.Error("CustomerModel 数据绑定出错", zap.Error(err))
	}
	return false

}

func (cust *CustomerModel) ListData(page, limitItems int, order string, name string, company string, customerStatus int) (totalCounts int64, tmp []*CustomerModel) {
	
	// var tmp []*CustomerModel
	counts := cust.getCountsByWhere(name, company, customerStatus)
	if counts == 0 {
		return 0, nil
	}
	query := cust.Model(cust)
	if name != "" {
		query = query.Where("name like ?", "%"+name+"%")
	}
	if company != "" {
		query = query.Where("company like ?", "%"+company+"%")
	}
	if customerStatus >  0 {
		query = query.Where("customer_status = ?", customerStatus)
	}
	query.Where("delete_status = ?", 1)
	if res := query.Limit(limitItems).Offset(page).Order(order).Find(&tmp); res.Error == nil {

		return counts, tmp

	} else {
		variable.ZapLog.Error("CustomerModel 数据查询出错", zap.Error(res.Error))
	}
	return 0, nil
}

func (cust *CustomerModel) ShowOneItem(id int) (tmp *CustomerModel) {
	if res := cust.Where("id = ?", id).First(&tmp); res.Error == nil && tmp.Id > 0 {
	
		return tmp
	} else {
		variable.ZapLog.Error("CustomerModel 数据查询出错", zap.Error(res.Error))
	}
	return nil

}

func (cust *CustomerModel) GetCustomerByIds(ids []int) (tmp []*CustomerModel) {
	if res := cust.Where("id in (?)", ids).Where("delete_status = ?", 1).Find(&tmp); res.Error == nil {
		return tmp
	}
	return nil
}

func (cust *CustomerModel) GetCustomerAllData(field []string) (totalCounts int64,tmp []*CustomerModel) {
	counts := cust.getCounts()
	if counts == 0 {
		return 0, nil
	}
	if res := cust.Select(field).Where("delete_status = ?", 1).Find(&tmp); res.Error == nil {
		return counts, tmp
	}
	return 0,nil
}

func (cust *CustomerModel) GetTotalStatusStatistics() (totalStatusStatistics *TotalStatusStatistics) {
	var tmp []*TotalStatusStatistics
	query := cust.Model(cust)
	query.Select("sum(case when customer_status = 0 then 1 else 0 end) as potential_user_num,sum(case when customer_status = 1 then 1 else 0 end) as active_user_num,sum(case when customer_status = 2 then 1 else 0 end) as churned_users_num")
	query.Where("delete_status = ?", 1)
	if err := query.First(&tmp).Error; err != nil {
		variable.ZapLog.Error("CustomerModel 数据查询出错", zap.Error(err))
	}
	if len(tmp) > 0 {
		totalStatusStatistics = tmp[0]
	}
	return totalStatusStatistics
}

func (cust *CustomerModel) DeleteData(id int) bool {
	if res := cust.Model(cust).Where("id = ?", id).Updates(map[string]interface{}{"delete_status": 2}); res.Error == nil {
		return true
	} else {
		variable.ZapLog.Error("CustomerModel DeleteData 数据更新出错", zap.Int("id", id), zap.Error(res.Error))
	}
	return false
}